import {
  Button,
  Card,
  Checkbox,
  Col,
  Divider,
  Form,
  FormItem,
  Input,
  InputSearch,
  Modal,
  Progress,
  RadioButton,
  RadioGroup,
  Row,
  Select,
  SelectOption,
  Space,
  Spin,
  Textarea,
  Tree,
  TreeSelect,
  Upload
} from 'ant-design-vue'
import { defineComponent, onMounted, ref } from 'vue'
import { Pager as VxePager } from 'vxe-table'

import { commonApi, materialApi } from '@/apis'
import type { GetVideoListRes, VideoItem } from '@/apis/materialTypes'
import { ProVideo, Scrollbar, SvgIcon } from '@/components'

import { useGroup, usePager, useToolbar, useVideo } from './hooks'
import styles from './index.module.css'
import type { SearchParams, VideoForm } from './types'

export default defineComponent({
  name: 'VideoManage',
  setup() {
    const videoData = ref([] as VideoItem[])
    const videoPage = ref({} as GetVideoListRes['page'])
    const searchParams = ref({
      name: '',
      format: '',
      groupId: undefined as any,
      pageParameter: {
        currentPage: 1,
        pageSize: 12
      }
    } as SearchParams)
    const getVideoListLoading = ref(false)
    const uploadVideoLoading = ref(false)

    /** 获取视频上限 */
    async function handleGetVideoLimit() {
      videoLimit.value = await materialApi.getVideoLimit()
    }

    /** 获取视频列表 */
    async function handleGetVideoList() {
      try {
        getVideoListLoading.value = true

        const data = await materialApi.getVideoList(searchParams.value)
        videoData.value = data.dataList
        videoPage.value = data.page

        /** 清空选中数据 */
        videoExports.selectedVideoIds.value.clear()
        videoExports.selectedAll.value = false
        videoExports.indeterminate.value = false
      } catch {
      } finally {
        getVideoListLoading.value = false
      }
    }

    const { groupData, handleGetGroupList, ...groupExports } = useGroup({
      searchParams,
      handleGetVideoList
    })
    const { ...videoExports } = useVideo({
      videoData,
      handleGetVideoList,
      handleGetGroupList,
      handleGetVideoLimit
    })
    const { videoLimit, ...toolbarExports } = useToolbar({
      searchParams,
      handleGetVideoList,
      handleGetVideoLimit,
      handleGetGroupList
    })
    const { ...pagerExports } = usePager({ searchParams, handleGetVideoList })

    /** 初始化 */
    function init() {
      handleGetGroupList()
      handleGetVideoList()
      handleGetVideoLimit()
    }

    /** 上传视频 */
    function handleUploadVideoChange(formModel: VideoForm, params: FileInfo) {
      console.log(params)

      if (params.file.status === 'uploading') {
        uploadVideoLoading.value = true
      }

      if (params.file.status === 'done') {
        uploadVideoLoading.value = false

        formModel.videoUrl = params.file.response.data
        formModel.cover = `${formModel.videoUrl}?x-oss-process=video/snapshot,t_1000,m_fast,f_jpg`
        formModel.size = (params.file as any).size
        formModel.suffix = (params.file.name as string)
          .split('.')[1]
          .toUpperCase()
      }

      if (params.file.status === 'error') {
        uploadVideoLoading.value = false
      }
    }

    /** 上传封面 */
    function handleUploadCoverChange(formModel: VideoForm, params: FileInfo) {
      if (params.file.status === 'done') {
        formModel.cover = params.file.response.data
      }
    }

    onMounted(() => {
      init()
    })

    return {
      videoData,
      videoPage,
      groupData,
      searchParams,
      getVideoListLoading,
      uploadVideoLoading,
      videoLimit,
      handleUploadVideoChange,
      handleUploadCoverChange,
      ...toolbarExports,
      ...groupExports,
      ...videoExports,
      ...pagerExports
    }
  },
  render() {
    const renderVideoForm = (
      formRef: any,
      formModel: any,
      formType: 'add' | 'edit'
    ) => (
      <Spin
        spinning={
          formType === 'add' ? this.addVideoLoading : this.editVideoLoading
        }
      >
        <Form class={styles.form} labelCol={{ span: 4 }}>
          <FormItem label="上传至分组">
            <TreeSelect
              v-model:value={formModel['groupId']}
              treeData={this.groupData}
              replaceFields={{
                key: 'key',
                value: 'key',
                title: 'title',
                children: 'children'
              }}
            ></TreeSelect>
          </FormItem>
          <FormItem label="视频名称" {...formRef.validateInfos['name']}>
            <Input v-model:value={formModel['name']} />
          </FormItem>
          <FormItem label="投放渠道" {...formRef.validateInfos['channel']}>
            <Select v-model:value={formModel['channel']}>
              {this.channelOptions.map(v => (
                <SelectOption value={v.value}>{v.label}</SelectOption>
              ))}
            </Select>
          </FormItem>
          <FormItem label="视频" {...formRef.validateInfos['videoUrl']}>
            <div class={styles.formItemVideo}>
              <Input
                v-model:value={formModel['videoUrl']}
                class={styles.formItemVideoInput}
                disabled
              />
              <Upload
                action={commonApi.uploadFileUrl}
                accept=".flv,.mp4"
                class={styles.formItemVideoUpload}
                showUploadList={false}
                onChange={args => this.handleUploadVideoChange(formModel, args)}
                disabled={formType === 'edit'}
              >
                <Button
                  type="primary"
                  loading={this.uploadVideoLoading}
                  disabled={formType === 'edit'}
                >
                  选择
                </Button>
              </Upload>
            </div>
          </FormItem>
          <FormItem label="封面" {...formRef.validateInfos['cover']}>
            {formModel.cover ? (
              <img class={styles.formItemCoverImg} src={formModel['cover']} />
            ) : (
              <div class={styles.formItemCoverEmpty}></div>
            )}
            <div class={styles.formItemCoverDesc}>
              <span>默认第一帧为封面</span>
              <Upload
                action={commonApi.uploadFileUrl}
                accept="image/*"
                showUploadList={false}
                onChange={args => this.handleUploadCoverChange(formModel, args)}
              >
                <Button type="link" size="small">
                  重新设置
                </Button>
              </Upload>
              <span>（最优尺寸：500*400）</span>
            </div>
          </FormItem>
          <FormItem label="简介">
            <Textarea
              v-model:value={formModel['description']}
              rows={4}
            ></Textarea>
          </FormItem>
        </Form>
      </Spin>
    )

    const renderVideoItem = (item: VideoItem) => (
      <div class={styles.videoItem}>
        <div
          class={styles.videoItemCoverWrap}
          onClick={() => this.handleShowPlayVideo(item)}
        >
          <div class={styles.videoItemPlayWrap}>
            <SvgIcon class={styles.videoItemPlayIcon} name="video-play" />
          </div>
          <img class={styles.videoItemCoverImg} src={item.cover} />
        </div>
        <div class={styles.videoItemContentWrap}>
          <div class={styles.videoItemRow}>
            <div class={styles.videoItemNameWrap}>
              <span class={styles.videoItemName}>{item.name}</span>
              <span class={styles.videoItemType}>({item.suffix})</span>
            </div>
            <Checkbox
              checked={this.selectedVideoIds.has(item.id)}
              onChange={value => this.handleSelectVideo(value, item)}
            ></Checkbox>
          </div>
          <div>
            <span class={styles.videoItemSize}>
              {this.getVideoSize(item.size)}
            </span>
            <span class={styles.videoItemCreateTime}>
              {item.uploadTime}上传
            </span>
          </div>
          <div class={styles.videoItemBtns}>
            <SvgIcon
              class={styles.videoItemBtn}
              name="edit"
              onClick={() => this.handleShowEditVideo(item)}
            />
            <Divider type="vertical" />
            <span class={styles.videoItemBtnBlock}></span>
            <Divider type="vertical" />
            <SvgIcon
              class={styles.videoItemBtn}
              name="delete"
              onClick={() => this.handleDeleteVideo(item)}
            />
          </div>
        </div>
      </div>
    )

    return (
      <div class={styles.view}>
        <Card>
          <Row>
            <Col span={12}>
              <div>
                <Button type="primary" ghost onClick={this.handleShowAddVideo}>
                  上传视频
                </Button>
                <span class={styles.numProgressTitle}>视频数量</span>
                <Progress
                  class={styles.numProgress}
                  percent={this.getLimitPercent()}
                  strokeWidth={4}
                  format={() =>
                    `${this.videoLimit.num}/${this.videoLimit.limit}`
                  }
                />
              </div>
              <div class={styles.typeWrap}>
                <span class={styles.typeTitle}>视频格式</span>
                <RadioGroup
                  v-model:value={this.searchParams.format}
                  onChange={this.handleFormatSearch}
                >
                  {this.typeOptions.map(v => (
                    <RadioButton value={v.value}>{v.label}</RadioButton>
                  ))}
                </RadioGroup>
              </div>
            </Col>
            <Col class={styles.searchInputWrap} span={12}>
              <InputSearch
                v-model:value={this.searchParams.name}
                class={styles.searchInput}
                enterButton="搜索"
                placeholder="视频名称"
                onSearch={this.handleInputSearch}
              />
            </Col>
          </Row>
        </Card>
        <div class={styles.contentWrap}>
          <Card class={styles.videoCard}>
            <Spin spinning={this.getVideoListLoading}>
              <div>
                <Checkbox
                  checked={this.selectedAll}
                  indeterminate={this.indeterminate}
                  onChange={value =>
                    this.handleSelectAllChange(value, this.videoData)
                  }
                >
                  全选
                </Checkbox>
                <Space>
                  <Button onClick={this.handleBatchDeleteVideo}>
                    批量删除
                  </Button>
                  <Button onClick={this.handleShowMove}>移动到</Button>
                </Space>
              </div>
              <div
                style={{
                  height: this.videoListHeight + 'px'
                }}
              >
                <Scrollbar>
                  <div class={styles.videoList}>
                    {this.videoData.map(renderVideoItem)}
                  </div>
                </Scrollbar>
              </div>
            </Spin>
          </Card>
          <Card class={styles.groupCard}>
            <Spin spinning={this.getGroupListLoading}>
              <div>
                <span>视频分组</span>
              </div>
              <InputSearch
                class={styles.groupInputSearch}
                placeholder="分组名称"
                enterButton="搜索"
                onSearch={this.handleSearchGroup}
              />
              <div class={styles.groupTreeWrap}>
                <Scrollbar>
                  <Tree
                    v-slots={{
                      title: this.getGroupTitle
                    }}
                    v-model:selectedKeys={this.selectedGroupKeys}
                    treeData={this.groupData}
                    expandedKeys={this.expandedGroupKeys}
                    onExpand={this.handleExpandGroup}
                    onSelect={this.handleSelectGroup}
                  ></Tree>
                </Scrollbar>
              </div>
            </Spin>
            <div class={styles.groupBtns}>
              <Space>
                <Button size="small" onClick={this.handleShowSubGroup}>
                  添加子分组
                </Button>
                <Button size="small" onClick={this.handleShowRenameGroup}>
                  重命名
                </Button>
                <Button size="small" onClick={this.handleDeleteGroup}>
                  删除分组
                </Button>
              </Space>
            </div>
          </Card>
        </div>
        <Divider class={styles.pagerDivider} />
        {/* 分页 */}
        <VxePager
          currentPage={this.videoPage.currentPage}
          pageSize={this.videoPage.pageSize}
          total={this.videoPage.totalCount}
          onPageChange={this.handlePageChange}
        />
        {/* 新建视频弹窗 */}
        <Modal
          v-model:visible={this.showAddVideo}
          title="新建视频"
          confirmLoading={this.addVideoLoading}
          onOk={this.addVideo}
          onCancel={this.handleCloseAddVideo}
        >
          {renderVideoForm(this.addVideoFormRef, this.addVideoFormModel, 'add')}
        </Modal>
        {/* 编辑视频弹窗 */}
        <Modal
          v-model:visible={this.showEditVideo}
          title="编辑视频"
          confirmLoading={this.editVideoLoading}
          onOk={this.editVideo}
          onCancel={this.handleCloseEditVideo}
        >
          {renderVideoForm(
            this.editVideoFormRef,
            this.editVideoFormModel,
            'edit'
          )}
        </Modal>
        {/* 移动分组弹窗 */}
        <Modal
          v-model:visible={this.showMove}
          title="移动分组"
          confirmLoading={this.moveGroupLoading}
          onOk={this.move}
          onCancel={this.handleCloseMove}
        >
          <p>
            您已选中{this.selectedVideoIds.size}个项目，将全部移动到以下分组：
          </p>
          <TreeSelect
            v-model:value={this.moveGroupId}
            treeData={this.groupData}
            replaceFields={{
              key: 'key',
              value: 'key',
              title: 'title',
              children: 'children'
            }}
            placeholder="请选择分组"
            style={{ width: '100%' }}
          ></TreeSelect>
        </Modal>
        {/* 播放视频弹窗 */}
        <Modal
          v-model:visible={this.showPlayVideo}
          footer={null}
          width={600}
          bodyStyle={{ padding: 0 }}
          closable={false}
          destroyOnClose={true}
          onCancel={this.handleClosePlayVideo}
        >
          <ProVideo ref="videoRef" {...this.videoConfig} />
        </Modal>
        {/* 子分组弹窗 */}
        <Modal
          v-model:visible={this.showSubGroup}
          title="新建分组名称"
          confirmLoading={this.addSubGroupLoading}
          onOk={this.addSubGroup}
          onCancel={this.handleCloseSubGroup}
        >
          <Form>
            <FormItem {...this.subGroupFormRef.validateInfos['name']}>
              <Input
                v-model:value={this.subGroupFormModel.name}
                v-slots={{
                  suffix: () => (
                    <span>{this.subGroupFormModel.name.length}/12</span>
                  )
                }}
                placeholder="请输入分组名称"
              />
            </FormItem>
          </Form>
        </Modal>
        {/* 重命名弹窗 */}
        <Modal
          v-model:visible={this.showRename}
          title="重命名分组名称"
          confirmLoading={this.renameSubGroupLoading}
          onOk={this.renameGroup}
          onCancel={this.handleCloseRenameGroup}
        >
          <Form>
            <FormItem {...this.renameFormRef.validateInfos['name']}>
              <Input
                v-model:value={this.renameFormModel.name}
                v-slots={{
                  suffix: () => (
                    <span>{this.renameFormModel.name.length}/12</span>
                  )
                }}
                placeholder="请输入分组名称"
              />
            </FormItem>
          </Form>
        </Modal>
      </div>
    )
  }
})
